home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / comm / bbs / s342q16.lha / va.c < prev    next >
C/C++ Source or Header  |  1996-08-29  |  24KB  |  914 lines

  1. /*
  2.  *                              va.c
  3.  *
  4.  * Virtual Room Administrator for the C-86 bulletin board system.
  5.  */
  6.  
  7. /*
  8.  *                              history
  9.  *
  10.  * 88Apr19 HAW  1.2: Fix for checking PEONS against local msgs.
  11.  * 88Apr08 HAW  1.1: Fix for not turning off a room's inuse flag.
  12.  * 88Jan19 HAW  Created.
  13.  */
  14.  
  15. #define V_ADMIN 1
  16.  
  17. #include "ctdl.h"
  18. #include "math.h"
  19. void VReName(void);
  20. int  mPrintf(char *format, ...) {return 0; }  /* stub to quiet the linker */
  21.  
  22. /*
  23.  *                              contents
  24.  *
  25.  */
  26.  
  27. FILE            *VaLog = NULL;
  28. char            *VersionString = "V3.42";
  29. char            RunMode;
  30. VirtualRoom     *VRoomTab = NULL;
  31. int             VirtSize;
  32. VirtNet         *VirtNetList = NULL;
  33.  
  34. extern MessageBuffer   msgBuf;          /* The -sole- message buffer    */
  35. extern CONFIG    cfg;                   /* Configuration variables      */
  36. extern aRoom     roomBuf;               /* Room buffer                  */
  37. extern rTable    *roomTab;
  38. extern NetTable  *netTab;
  39. extern NetBuffer netBuf;
  40. extern FILE      *netfl, *roomfl;
  41.  
  42. extern FILE *msgfl, *msgfl2;
  43.  
  44. extern int       thisRoom;              /* Current room */
  45. extern int       thisNet;               /* Current node in use */
  46.  
  47. /*
  48.  * main()
  49.  *
  50.  * This is the main manager.
  51.  */
  52. int main(int , char **);
  53. int main(argc, argv)
  54. char **argv;
  55. int  argc;
  56. {
  57.     cfg.weAre = UTILITY;
  58.     if (!readSysTab(TRUE, TRUE)) {
  59.         exit(1);
  60.     }
  61.  
  62.     if (access(LOCKFILE, 0) != ERROR) {
  63.         printf("Please do not run VirtAdmn using Outside Commands.\n");
  64.         writeSysTab();
  65.         exit(1);
  66.     }
  67.  
  68.     GenInit();
  69.     InitVirtual();      /* kludge ... ? */
  70.     AnalyzeArguments(argc, argv);
  71.     splitIt("Citadel-86 Virtual Room Administrator %s\n%s\n", VersionString,
  72.         COPYRIGHT);
  73.     splitIt("\nNode is %s\n", cfg.nodeName + cfg.codeBuf);
  74.     switch (RunMode) {
  75.         case BATCH:
  76.                 splitIt("Batch mode.\n");
  77.                 BatchMode();
  78.                 break;
  79.         case NORMAL:
  80.                 splitIt("\n\n\n");
  81.                 InteractMode();
  82.                 break;
  83.         default: splitIt("very bad value for run mode!");
  84.     }
  85.     writeSysTab();
  86.     UpdVirtStuff();             /* kludge ... ? */
  87. return 0;
  88. }
  89.  
  90. /*
  91.  * GenInit()
  92.  *
  93.  * This does general initialization.
  94.  */
  95. void GenInit()
  96. {
  97.     SYS_FILE fn;
  98.  
  99.     initNetBuf(&netBuf);
  100.     makeSysName(fn, "ctdlnet.sys", &cfg.netArea);
  101.     openFile(fn, &netfl);
  102.  
  103.     initRoomBuf(&roomBuf);
  104.     makeSysName(fn, "ctdlroom.sys", &cfg.roomArea);
  105.     openFile(fn, &roomfl);
  106.  
  107.     makeSysName(fn, "ctdlmsg.sys", &cfg.msgArea);
  108.     openFile(fn, &msgfl);
  109. }
  110.  
  111. /*
  112.  * InitVirtual()
  113.  *
  114.  * This will read in the virtual stuff, create if necessary.
  115.  */
  116. void InitVirtual()
  117. {
  118.     FILE        *fd, *safeopen();
  119.     SYS_FILE    fn;
  120.     int         i, j;
  121.     long        len;
  122.     extern char *R_W_ANY, *W_R_ANY;
  123.  
  124.     ChkVirtArea();
  125.  
  126.     makeVASysName(fn, "ctdlvrm.sys");
  127.     if ((fd = safeopen(fn, R_W_ANY)) == NULL) {
  128.         splitIt("%s missing, creating it.\n", fn);
  129.         if ((fd = safeopen(fn, W_R_ANY)) == NULL) {
  130.             splitIt("Couldn't create the virtual room table!");
  131.             exit(1);
  132.         }
  133.         VirtSize = 0;
  134.     }
  135.     else {
  136.         totalBytes(&len, fd);
  137.         VRoomTab = (VirtualRoom *) GetDynamic((unsigned) len);
  138.         fread(VRoomTab, (int) len, 1, fd);
  139.         VirtSize = (int) ((int) len / sizeof *VRoomTab);
  140.     }
  141.     fclose(fd);
  142.  
  143.     VirtNetList = (VirtNet *)
  144.                         GetDynamic(cfg.netSize * (sizeof *VirtNetList));
  145.     makeVASysName(fn, "ctdlvnet.sys");
  146.     if ((fd = safeopen(fn, R_W_ANY)) == NULL) {
  147.         splitIt("%s missing, creating it.\n", fn);
  148.         if ((fd = safeopen(fn, W_R_ANY)) == NULL) {
  149.             splitIt("Couldn't create the network's virtual list (%s)!", fn);
  150.             exit(1);
  151.         }
  152.         for (i = 0; i < cfg.netSize; i++) {
  153.             for (j = 0; j < VIRT_LIMIT; j++) {
  154.                 VirtNetList[i].VirtList[j].WhichVirt = -1;      /* not in use */
  155.             }
  156.         }
  157.         fwrite(VirtNetList, sizeof *VirtNetList, cfg.netSize, fd);
  158.     }
  159.     else fread(VirtNetList, cfg.netSize * (sizeof *VirtNetList), 1, fd);
  160.     fclose(fd);
  161. }
  162.  
  163. /*
  164.  * UpdVirtStuff()
  165.  *
  166.  * This will update the disk about the virtual stuff.
  167.  */
  168. void UpdVirtStuff()
  169. {
  170.     FILE *fd, *safeopen();
  171.     SYS_FILE fn;
  172.     extern char *R_W_ANY;
  173.  
  174.     makeVASysName(fn, "ctdlvrm.sys");
  175.     if ((fd = safeopen(fn, R_W_ANY)) == NULL)
  176.         crashout("ctdlvrm.sys is missing!");
  177.  
  178.     fwrite(VRoomTab, VirtSize, sizeof *VRoomTab, fd);
  179.     fclose(fd);
  180.  
  181.     makeVASysName(fn, "ctdlvnet.sys");
  182.     if ((fd = safeopen(fn, R_W_ANY)) == NULL)
  183.         crashout("ctdlvnet.sys is missing!!");
  184.  
  185.     fwrite(VirtNetList, cfg.netSize, sizeof *VirtNetList,  fd);
  186.     fclose(fd);
  187. }
  188.  
  189. /*
  190.  * AnalyzeArguments()
  191.  *
  192.  * what are we to do???
  193.  */
  194. void AnalyzeArguments(argc, argv)
  195. int  argc;
  196. char **argv;
  197. {
  198.     int  rover;
  199.     SYS_FILE    fn;
  200.     extern char *APPEND_TEXT;
  201.  
  202.     RunMode = NORMAL;
  203.  
  204.     for (rover = 1; rover < argc; rover++) {
  205.         if (strCmpU(argv[rover], "+log") == SAMESTRING) {
  206.             makeSysName(fn, "netlog.sys", &cfg.netArea);
  207.             VaLog = safeopen(fn, APPEND_TEXT);
  208.         }
  209.         else if (strCmpU(argv[rover], "+batch") == SAMESTRING) {
  210.             RunMode = BATCH;
  211.         }
  212.     }
  213. }
  214.  
  215. /*
  216.  * InteractMode()
  217.  *
  218.  * This lets us talk to da sysop.
  219.  */
  220. void InteractMode()
  221. {
  222.     int answer;
  223.  
  224.     do {
  225.         splitIt("\n\n%30cVirtual Administrator Menu\n\n", ' ');
  226.         splitIt("A. Display Virtual Rooms.\n");
  227.         splitIt("B. Add a Virtual Room.\n");
  228.         splitIt("C. Modify a Virtual Room.\n");
  229.         splitIt("D. Delete a Virtual Room.\n");
  230.         splitIt("E. Convert a normal room to a virtual room.\n");
  231.         splitIt("F. Rename room.\n");
  232.         splitIt("Z. Exit the Virtual Room Administrator.\n");
  233.         switch ((answer = toUpper(NEUtilGetch()))) {
  234.         case 'A':
  235.                 Display();                      break;
  236.         case 'B':
  237.                 AddRoom();                      break;
  238.         case 'C':
  239.                 Modify();                       break;
  240.         case 'D':
  241.                 Delete();                       break;
  242.         case 'E':
  243.                 ConNorVa();                     break;
  244.         case 'F':
  245.                 VReName();                      break;
  246.         case 'Y':
  247.                 VADebug();                      break;
  248.         case 'Z':
  249.                                                 break;
  250.         default:
  251.                 printf("\007\n\n\n");           break;
  252.         }
  253.     } while (answer != EOF && answer != 'Z');
  254. }
  255.  
  256. /*
  257.  * AddRoom()
  258.  *
  259.  * This function will add a virtual room.
  260.  */
  261. void AddRoom()
  262. {
  263.     int   rover;
  264.     label NewName;
  265.     void  *realloc();
  266.  
  267.     if (GetConString("room name", NewName, NAMESIZE)) {
  268.         if (roomExists(NewName) != ERROR) {
  269.             splitIt("A real room by that name already exists.\n");
  270.             return ;
  271.         }
  272.         if (VirtualExists(NewName) != ERROR) {
  273.             splitIt("A virtual room by that name already exists.\n");
  274.             return ;
  275.         }
  276.  
  277.         rover = Add2Room(NewName);
  278.  
  279.         GetInputList(rover, "Nodes to be added to this virtual room's list",
  280.                                                 AddNodes);
  281.     }
  282. }
  283.  
  284. /*
  285.  * Add2Room()
  286.  *
  287.  * This does the rest of adding a room.
  288.  */
  289. int Add2Room(label NewName)
  290. {
  291.     int rover;
  292.  
  293.     for (rover = 0; rover < VirtSize; rover++)
  294.         if (!VRoomInuse(rover)) break;
  295.  
  296.     if (rover == VirtSize) {
  297.         if (rover == 0)
  298.             VRoomTab = (VirtualRoom *) GetDynamic(sizeof *VRoomTab);
  299.         else
  300.             VRoomTab = realloc(VRoomTab, (rover+1) * sizeof *VRoomTab);
  301.         VirtSize++;
  302.     }
  303.  
  304.     strCpy(VRoomTab[rover].vrName, NewName);
  305.  
  306.     VRoomTab[rover].vrHiLocal =
  307.     VRoomTab[rover].vrHiLD    =
  308.     VRoomTab[rover].vrLoLocal =
  309.     VRoomTab[rover].vrLoLD    = 0l;
  310.     SetVirtAreas(rover);
  311.  
  312.     return rover;
  313. }
  314.  
  315. /*
  316.  * VirtualExists()
  317.  *
  318.  * This function will check for existence of a virtual room.
  319.  */
  320. int VirtualExists(name)
  321. label name;
  322. {
  323.     int rover;
  324.  
  325.     for (rover = 0; rover < VirtSize; rover++)
  326.         if (strCmpU(VRoomTab[rover].vrName, name) == SAMESTRING) return rover;
  327.  
  328.     return ERROR;
  329. }
  330.  
  331. /*
  332.  * Delete()
  333.  *
  334.  * This function will delete a room from the virtual room table.
  335.  */
  336. void Delete()
  337. {
  338.     label NewName;
  339.     int   slot;
  340.  
  341.     if (GetConString("room name", NewName, NAMESIZE)) {
  342.         if ((slot = VirtualExists(NewName)) != ERROR)
  343.             if (getYesNo("confirm")) {
  344.                 VRoomKill(slot);
  345.                 KillVirtAreas(slot);
  346.                 ResetNodes(slot);
  347.             }
  348.     }
  349. }
  350.  
  351. /*
  352.  * ResetNodes()
  353.  *
  354.  * This function negates nodes attachments to a dead room.
  355.  */
  356. void ResetNodes(slot)
  357. int slot;
  358. {
  359.     int rover, j;
  360.  
  361.     for (rover = 0; rover < cfg.netSize; rover++) {
  362.         for (j = 0; j < VIRT_LIMIT; j++) {
  363.             if (VirtNetList[rover].VirtList[j].WhichVirt == slot)
  364.                 VirtNetList[rover].VirtList[j].WhichVirt = -1;
  365.         }
  366.     }
  367. }
  368.  
  369. /*
  370.  * GetConString()
  371.  *
  372.  * This function will get info from console.
  373.  */
  374. char GetConString(prompt, buffer, length)
  375. char *prompt, *buffer;
  376. int length;
  377. {
  378.     int count = 0, c;
  379.  
  380.     if (strLen(prompt) != 0)
  381.         splitIt("Enter %s (ESC to abort)", prompt);
  382.  
  383.     splitIt("\n : ");
  384.     while (c = UtilGetch(), c != '\r' && c != '\n' && c != ESC) {
  385.         if ((c != '\b' && count == length) ||
  386.             (c == '\b' && count == 0)) {
  387.             if (c != '\b') splitIt("\b \b\007");
  388.             else           splitIt("\007");
  389.         }
  390.         else if (c != '\b') {
  391.             buffer[count++] = c;
  392.         }
  393.         else {
  394.             splitIt(" \b");
  395.             count--;
  396.         }
  397.     }
  398.     buffer[count] = 0;
  399.     if (c == ESC || strLen(buffer) == 0)
  400.         return FALSE;
  401.     return TRUE;
  402. }
  403.  
  404. /*
  405.  * getYesNo()
  406.  *
  407.  * This gets a Y/N question of the user.
  408.  */
  409. char getYesNo(question)
  410. char *question;
  411. {
  412.     int c;
  413.  
  414.     do {
  415.         splitIt("\n%s (Y/N)? ", question);
  416.         c = toUpper(UtilGetch());
  417.     } while (c != 'Y' && c != 'N');
  418.     return (char)( (c == 'Y') ? TRUE : FALSE);
  419. }
  420.  
  421. /*
  422.  * Modify()
  423.  *
  424.  * This function will add and kill nodes from a sharing list.
  425.  */
  426. void Modify()
  427. {
  428.     label NewName;
  429.     int   slot, AddNodes(), RemoveNodes();
  430.  
  431.     if (GetConString("room name", NewName, NAMESIZE)) {
  432.         if ((slot = VirtualExists(NewName)) == ERROR) {
  433.             splitIt("'%s' does not exist.\n", NewName);
  434.             return ;
  435.         }
  436.         GetInputList(slot, "Nodes to be added to this virtual room's list",
  437.                                                 AddNodes);
  438.         GetInputList(slot, "Nodes to be taken off this virtual room's list",
  439.                                                 RemoveNodes);
  440.         GetInputList(slot, "Nodes to be changed", ChgNodes);
  441.     }
  442. }
  443.  
  444. /*
  445.  * GetInputList()
  446.  *
  447.  * This function will process lists entered by user.
  448.  */
  449. void GetInputList(index, prompt, func)
  450. int index, (*func)(int index, label name);
  451. char *prompt;
  452. {
  453.     label data;
  454.  
  455.     splitIt(prompt);
  456.     while (GetConString("", data, NAMESIZE))
  457.         if (!(*func)(index, data)) break;
  458. }
  459.  
  460. /*
  461.  * AddNodes()
  462.  *
  463.  * This adds a node to room's share list.
  464.  */
  465. int AddNodes(index, name)
  466. int index;
  467. label name;
  468. {
  469.     int rover, system, c, found;
  470.  
  471.     if ((system = searchNameNet(name, &netBuf)) == ERROR) {
  472.         splitIt("No such system known.");
  473.         return TRUE;
  474.     }
  475.  
  476.     for (rover = 0, found = FALSE; rover < VIRT_LIMIT; rover++)
  477.         if (index == VirtNetList[system].VirtList[rover].WhichVirt) {
  478.             found = TRUE;
  479.             break;
  480.         }
  481.  
  482.     if (!found)
  483.         for (rover = 0; rover < VIRT_LIMIT; rover++)
  484.             if (VirtNetList[system].VirtList[rover].WhichVirt == -1) {
  485.                 break;
  486.             }
  487.  
  488.     if (rover == VIRT_LIMIT) {
  489.         splitIt("Sorry, no room.");
  490.         return TRUE;
  491.     }
  492.  
  493.     if (!getYesNo("Is this system a Peon")) {
  494.         do {
  495.             splitIt("\nWill we be a <P>assive or <A>ctive backbone? ");
  496.             c = toUpper(UtilGetch());
  497.         } while (c != 'A' && c != 'P');
  498.         VirtNetList[system].VirtList[rover].mode =
  499.         (c == 'A') ? ACTIVE_BACKBONE : PASS_BACKBONE;
  500.     }
  501.     else
  502.         VirtNetList[system].VirtList[rover].mode = PEON;
  503.  
  504.     VirtNetList[system].VirtList[rover].WhichVirt = index;
  505.  
  506.     if (!found) {
  507.         VirtNetList[system].VirtList[rover].LocSent   =
  508.            VRoomTab[index].vrLoLocal;
  509.         VirtNetList[system].VirtList[rover].LDSent    =
  510.            VRoomTab[index].vrLoLD;
  511.     }
  512.  
  513.     return TRUE;
  514. }
  515.  
  516. /*
  517.  * RemoveNodes()
  518.  *
  519.  * This function will remove a node from a room's share list.
  520.  */
  521. int RemoveNodes(index, name)
  522. int index;
  523. label name;
  524. {
  525.     int system, rover;
  526.  
  527.     if ((system = searchNameNet(name, &netBuf)) == ERROR) {
  528.         splitIt("No such system known.\n");
  529.         return TRUE;
  530.     }
  531.     for (rover = 0; rover < VIRT_LIMIT; rover++)
  532.         if (index == VirtNetList[system].VirtList[rover].WhichVirt) {
  533.             VirtNetList[system].VirtList[rover].WhichVirt = -1;
  534.             return TRUE;
  535.         }
  536.     return TRUE;
  537. }
  538.  
  539. /*
  540.  * ChgNodes()
  541.  *
  542.  * This function will change a node's status.
  543.  */
  544. int ChgNodes(index, name)
  545. int index;
  546. label name;
  547. {
  548.     int system, rover;
  549.  
  550.     if ((system = searchNameNet(name, &netBuf)) == ERROR) {
  551.         splitIt("No such system known.\n");
  552.         return TRUE;
  553.     }
  554.     for (rover = 0; rover < VIRT_LIMIT; rover++)
  555.         if (index == VirtNetList[system].VirtList[rover].WhichVirt) {
  556.             splitIt("Currently, ");
  557.             switch (VirtNetList[system].VirtList[rover].mode) {
  558.             case PEON:
  559.                 splitIt("you think of %s as a Peon.", name); break;
  560.             case ACTIVE_BACKBONE:
  561.                 splitIt("you are an Active Backbone for %s.", name); break;
  562.             case PASS_BACKBONE:
  563.                 splitIt("you are a Passive Backbone for %s.", name); break;
  564.             }
  565.  
  566.             splitIt("\nDo you wish to change the relationship to\n");
  567.             splitIt("1. Peon\n2. You are Active Backbone\n");
  568.             splitIt("3. Passive Backbone.\n? ");
  569.  
  570.             switch (NEUtilGetch()) {
  571.             case '1':
  572.             VirtNetList[system].VirtList[rover].mode = PEON; break;
  573.             case '2':
  574.             VirtNetList[system].VirtList[rover].mode = ACTIVE_BACKBONE; break;
  575.             case '3':
  576.             VirtNetList[system].VirtList[rover].mode = PASS_BACKBONE; break;
  577.             }
  578.  
  579.             return TRUE;
  580.         }
  581.     return TRUE;
  582. }
  583.  
  584. /*
  585.  * crashout()
  586.  *
  587.  * This handles fatal errors.
  588.  */
  589. void crashout(str)
  590. char *str;
  591. {
  592.     printf(str);
  593.     writeSysTab();
  594.     UpdVirtStuff();
  595.     exit(1);
  596. }
  597.  
  598. /*
  599.  * BatchMode()
  600.  *
  601.  * This handles batch mode calls.
  602.  */
  603. void BatchMode()
  604. {
  605.     struct Table_Summary {
  606.         MSG_NUMBER LoLocal, LoLD;
  607.     } *Summary;
  608.     int rover, checker, x;
  609.     MSG_NUMBER msgrover;
  610.     char buf[100];
  611.  
  612.     if (VirtSize == 0) return;
  613.  
  614.     Summary = (struct Table_Summary *) GetDynamic(VirtSize * sizeof *Summary);
  615. /*
  616.  * For each virtual room in use:
  617.  *
  618.  * 1. Determine which PEON-generated messages have been delivered to
  619.  *    all BACKBONES and kill those messages.
  620.  * 2. Update appropriate values.
  621.  * 3. Determine which BACKBONE-generated messages have been delivered to
  622.  *    other BACKBONES and PEONS, and kill them.
  623.  * 4. Update appropriate values.
  624.  *
  625.  *   The code that accepts and places messages in the correct places resides
  626.  * in the main source, not here.  Briefly:
  627.  *
  628.  * a. Each Virtual Room has a directory within the VIRTUAL\ subdirectory
  629.  *    dedicated to it.  Mapping of Room to directory is to use the slot # of
  630.  *    the Virtual room as a string for the directory name.  This will limit the
  631.  *    system to, at best, 11 digits.  Even if the limit is 8 digits, however,
  632.  *    that should be more than adequate.
  633.  * b. Each Room's subdirectory consists of two more subdirectories, arbitrarily
  634.  *    labeled.  Messages which arrive from BACKBONE systems
  635.  *    are placed in the "ld" directory; messages from PEONS are placed in the
  636.  *    "local" directory.
  637.  * c. Message structure: Each message that is accepted from another system is
  638.  *    NOT kept in a separate file.  Rather, each packet of messages is kept
  639.  *    in a file.  This should work just as well, and save on clutter.
  640.  * d. Each file kept in either directory will be given a name consisting of an
  641.  *    integer generated by incrementing a counter associated with that
  642.  *    directory.  Counters are independent of each other.
  643.  * e. The Virtual net list is used to track who needs what, using these
  644.  *    counters.  When messages are sent to a system, the number of the last
  645.  *    packet sent is recorded.  Possible problem: a BACKBONE calling -- how
  646.  *    do we keep from looping the messages back to the caller on the LD room
  647.  *    share?  OK, looks like we'll have to put it in a temp file, and rename
  648.  *    it later.  No, we can just remember to increment the number later, and
  649.  *    just not resend it now.
  650.  */
  651.     for (rover = 0; rover < VirtSize; rover++)
  652.         Summary[rover].LoLocal = Summary[rover].LoLD = 0xffffffffl;
  653.  
  654.     for (rover = 0; rover < cfg.netSize; rover++) {
  655.         if (netTab[rover].ntflags.in_use)
  656.         for (checker = 0; checker < VIRT_LIMIT; checker++) {
  657.             if ((x = VirtNetList[rover].VirtList[checker].WhichVirt) >= 0 &&
  658.                                 x < VirtSize) {
  659. /* splitIt("x is %d\n", x); */
  660. /* if (x > VirtSize) splitIt("BINGO!\n"); */
  661.                 if (VirtNetList[rover].VirtList[checker].mode != PEON)
  662.                     Summary[x].LoLocal =
  663.       min(Summary[x].LoLocal, VirtNetList[rover].VirtList[checker].LocSent);
  664.                 Summary[x].LoLD =
  665.       min(Summary[x].LoLD, VirtNetList[rover].VirtList[checker].LDSent);
  666.             }
  667.             else if (x >= VirtSize) {
  668.                 splitIt("x is high for system %d, correcting.\n", rover);
  669.                 VirtNetList[rover].VirtList[checker].WhichVirt = -1;
  670.             }
  671.         }
  672.     }
  673.  
  674.     for (rover = 0; rover < VirtSize; rover++) {
  675.         if (VRoomInuse(rover)) {
  676.  
  677.             if (Summary[rover].LoLocal == 0xffffffffl)
  678.                 Summary[rover].LoLocal = 0l;
  679.             if (Summary[rover].LoLD == 0xffffffffl)
  680.                 Summary[rover].LoLD = 0l;
  681.  
  682.             for (msgrover = max(VRoomTab[rover].vrLoLocal, 1l);
  683.                  msgrover <= Summary[rover].LoLocal; msgrover++) {
  684.                 CreateVAName(buf, rover, LOCAL_DIR, msgrover);
  685.                 splitIt("Unlinking %s\n", buf);
  686.                 unlink(buf);
  687.             }
  688.             VRoomTab[rover].vrLoLocal = msgrover;
  689.             for (msgrover = max(VRoomTab[rover].vrLoLD, 1l);
  690.                  msgrover <= Summary[rover].LoLD; msgrover++) {
  691.                 CreateVAName(buf, rover, LD_DIR, msgrover);
  692.                 splitIt("Unlinking %s\n", buf);
  693.                 unlink(buf);
  694.             }
  695.             VRoomTab[rover].vrLoLD = msgrover;
  696.         }
  697.     }
  698.  
  699.     free(Summary);
  700. }
  701.  
  702. /*
  703.  * roomExists()
  704.  *
  705.  * This will check for existence of a real room.
  706.  */
  707. int roomExists(room)
  708. char *room;
  709. {
  710.     int i;
  711.  
  712.     for (i = 0;  i < MAXROOMS;  i++) {
  713.         if (
  714.             roomTab[i].rtflags.INUSE == 1   &&
  715.             strCmpU(room, roomTab[i].rtname) == SAMESTRING
  716.         ) {
  717.             return(i);
  718.         }
  719.     }
  720.     return(ERROR);
  721. }
  722.  
  723. /*
  724.  * Display()
  725.  *
  726.  * This will give a crude display of virtual rooms and nodes attached.
  727.  */
  728. void Display()
  729. {
  730.     int rover, i, len, netRover;
  731.     char first;
  732.  
  733.     splitIt("\n\n\nVirtual Room Display\n\n");
  734.     for (rover = 0; rover < VirtSize; rover++) {
  735.         if (VRoomInuse(rover)) {
  736.             splitIt("%s> ", VRoomTab[rover].vrName);
  737.             for (i = strLen(VRoomTab[rover].vrName); i < 22; i++)
  738.                 splitIt(".");
  739.             splitIt(" ");
  740.             len = 44;   /* crude formatter */
  741.             first = TRUE;
  742.             for (netRover = 0; netRover < cfg.netSize; netRover++) {
  743.                 if (DoesShare(netRover, rover) != ERROR) {
  744.                     getNet(netRover, &netBuf);
  745.                     if (!first)
  746.                         splitIt(", ");
  747.                     else first = FALSE;
  748.                     if (2 + len + strLen(netBuf.netName) > 80) {
  749.                         splitIt("\n%24c", ' ');
  750.                         len = 23;
  751.                     }
  752.                     splitIt("%s", netBuf.netName);
  753.                     len += (2 + strLen(netBuf.netName));
  754.                 }
  755.             }
  756.             splitIt("\n");
  757.         }
  758.     }
  759. }
  760.  
  761. /*
  762.  * DoesShare()
  763.  *
  764.  * This function will find out if the given node shares the given room.
  765.  */
  766. int DoesShare(NodeNo, RoomNo)
  767. int NodeNo, RoomNo;
  768. {
  769.     int i;
  770.  
  771.     if (!netTab[NodeNo].ntflags.in_use) return ERROR;
  772.  
  773.     for (i = 0; i < VIRT_LIMIT; i++) {
  774.         if (VirtNetList[NodeNo].VirtList[i].WhichVirt == RoomNo)
  775.             return i;
  776.     }
  777.     return ERROR;
  778. }
  779.  
  780. void VADebug()
  781. {
  782.     int i, j, x;
  783.  
  784.     for (i = 0; i < cfg.netSize; i++) {
  785.         for (j = 0; j < VIRT_LIMIT; j++) {
  786.             if ((x=VirtNetList[i].VirtList[j].WhichVirt) != -1) {
  787.                 if (VRoomInuse(x)) {
  788.                     getNet(i, &netBuf);
  789.                     printf("%s for %s: ", netBuf.netName,
  790.                                 VRoomTab[x].vrName);
  791.                     printf("LocSent=%ld, LocHi=%ld, ",
  792.                               VirtNetList[i].VirtList[j].LocSent,
  793.                               VRoomTab[x].vrHiLocal);
  794.                     printf("LDSent=%ld, LDHI=%ld\n",
  795.                               VirtNetList[i].VirtList[j].LDSent,
  796.                               VRoomTab[x].vrHiLD);
  797.                 }
  798.             }
  799.         }
  800.     }
  801. }
  802.  
  803. /*
  804.  * ConNorVa()
  805.  *
  806.  * This function converts a normal room to a virtual
  807.  * 1. Make new virtual room.
  808.  * 2. Convert msg base messages to files, one per msg.  Route to correct
  809.  *    directories
  810.  * 3. Update VirtNetList.
  811.  * 4. Delete old room.
  812.  */
  813. void ConNorVa()
  814. {
  815.     int   rover, roomNo;
  816.     label Name;
  817.     void  *realloc();
  818.     TempData *List;
  819.  
  820.     if (GetConString("Normal room name", Name, NAMESIZE)) {
  821.         if ((roomNo = roomExists(Name)) == ERROR) {
  822.             splitIt("There is no room by that name.\n");
  823.             return ;
  824.         }
  825.  
  826.         if (!getYesNo("confirm")) return ;
  827.  
  828.         rover = Add2Room(Name);
  829.  
  830.         getRoom(roomNo);
  831.  
  832.         if (roomBuf.rbShareType == PEON)
  833.             splitIt("Warning: %s is not being backboned at the present time.\n",
  834.                                 roomBuf.rbname);
  835.  
  836.         List = SetNtoVList(roomNo, rover);
  837.  
  838.         NorToVirtual(rover, List);
  839.  
  840.         roomBuf.rbflags.INUSE = FALSE;
  841.  
  842.         putRoom(roomNo);
  843.  
  844.         roomTab[roomNo].rtflags.INUSE = FALSE;
  845.  
  846.         writeSysTab();
  847.     }
  848. }
  849.  
  850. /*
  851.  * VRename
  852.  *
  853.  * This function renames a virtual room.
  854.  */
  855. void VReName()
  856. {
  857.     label NewName, OldName;
  858.     int slot;
  859.  
  860.     if (!GetConString("old room name", OldName, NAMESIZE)) return;
  861.  
  862.     if ((slot = VirtualExists(OldName)) != ERROR) {
  863.         if (GetConString("new room name", NewName, NAMESIZE)) {
  864.             if (roomExists(NewName) != ERROR) {
  865.                 splitIt("A real room by that name already exists.\n");
  866.                 return ;
  867.             }
  868.             if (VirtualExists(NewName) != ERROR) {
  869.                 splitIt("A virtual room by that name already exists.\n");
  870.                 return ;
  871.             }
  872.             strCpy(VRoomTab[slot].vrName, NewName);
  873.         }
  874.     }
  875.     else splitIt("No such virtual room.\n");
  876. }
  877.  
  878. #ifdef NEEDED
  879. void LogSetup()
  880. {
  881. }
  882.  
  883. FILE *lfd = NULL;
  884. extern LogTable    *logTab;
  885. LogTable    *delogTab;
  886. void LogCheck(char *x)
  887. {
  888.     int i;
  889.  
  890.     if (lfd != NULL) return;
  891.     if (delogTab == NULL) {
  892.         delogTab = (LogTable *) GetDynamic(sizeof (*logTab) * cfg.MAXLOGTAB);
  893.         memcpy(delogTab, logTab, (long)sizeof (*logTab) * cfg.MAXLOGTAB);
  894.     }
  895.     for (i = 0; i < cfg.MAXLOGTAB; i++)
  896.         if (logTab[i].ltlogSlot >= cfg.MAXLOGTAB ||
  897.             logTab[i].ltlogSlot < 0 ||
  898.             logTab[i].ltpwhash != delogTab[i].ltpwhash ||
  899.             logTab[i].ltnmhash != delogTab[i].ltnmhash) {
  900.             if ((lfd = fopen("debug", "a")) != NULL) {
  901.                 fprintf(lfd, "Blargh at -%s- in VIRTADMN for index %d!\n",
  902.                                         x, i);
  903.                 fclose(lfd);
  904.             }
  905.             else printf("Blargh at -%s-!\n", x);
  906.             break;
  907.         }
  908. }
  909.  
  910. void splitF(FILE *log, char *fmt, ...)
  911. {
  912. }
  913. #endif
  914.